package com.example.passport.service;

import com.example.common.exception.BusinessException;
import com.example.common.exception.TokenInvalidException;
import com.example.common.util.StrUtil;
import com.example.front.component.WebSocketServer;
import com.example.passport.dto.TokenDto;
import com.example.passport.entity.Logging;
import com.example.passport.entity.Token;
import com.example.passport.entity.User;
import com.example.passport.mapper.TokenMapper;
import com.example.passport.mapper.UserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.websocket.Session;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.ThreadLocalRandom;

@Service
public class TokenService {

    @Resource
    WebSocketServer webSocketServer;

    @Resource
    UserMapper userMapper;

    @Resource
    TokenMapper tokenMapper;

    @Resource
    LoggingService loggingService;
    @Transactional
    public TokenDto createToken(String mobile, String password,String ip,String loginEquipment) {

        User user = userMapper.findByMobile(mobile);
        if (user == null) {
            throw new BusinessException("用户名或密码不匹配");
        }

        if (!StrUtil.md5((password + user.getPasswordSalt())).equals(user.getPasswordHash())) {
            throw new BusinessException("用户名或密码不匹配");
        }

        if (user.getStatus() != User.STATUS_ENABLE) {
            throw new BusinessException("帐号状态异常");
        }

        String token = StrUtil.randomString(32);
        tokenMapper.create(user.getId(), token);
        Logging logging=new Logging();
        logging.setLoginTime(new Date());
        logging.setUserId(user.getId());
        logging.setLoginEquipment(loginEquipment);
        logging.setIp(ip);
        logging.setTenantId(user.getTenantId());
        loggingService.createLogging(logging);
        return TokenDto.builder().token(token).userId(user.getId()).build();
    }

    @Transactional
    public void deleteToken(String token, long id) {

        if (tokenMapper.delete(token, id) == 0) {
            throw new BusinessException("操作异常");
        }
        Logging logging=new Logging();
        logging.setUserId(id);
//        User user=userMapper.findById(id);
//        webSocketServer.onClose(session,user.getApiToken());
        loggingService.update(logging);
    }

    public User getUserByToken(String tokenStr) {

        int duration = 60 * 60 * 24;   // token 有效时间长 (秒)

        if (tokenStr == null) {
            throw new TokenInvalidException("请登录");
        }

        Token token = tokenMapper.findByToken(tokenStr);
        if (token == null) {
            throw new TokenInvalidException("请登录");
        }

        if (new Date().getTime() - token.getCreatedAt().getTime() > duration * 1000) {
            throw new TokenInvalidException("请登录");
        }

        User user = userMapper.findById(token.getUserId());
        if (user == null || user.getStatus() != User.STATUS_ENABLE) {
            throw new TokenInvalidException("请登录");
        }

        // 清理过期的token 概率为0.1%
        if (ThreadLocalRandom.current().nextInt(0, 1000000) < 1000) {
            deleteInvalid();
        }

        return user;
    }


    public void deleteInvalid() {

        // token 有效时间长 (秒)
        int duration = 60 * 60 * 24;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.SECOND, -duration);
        tokenMapper.deleteInvalid(calendar.getTime());
    }
}
